home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug232 / parser.y < prev    next >
Text File  |  1987-06-17  |  12KB  |  419 lines

  1. /*
  2.     Little Smalltalk Class method syntax
  3.         
  4.         differs from smalltalk-80 slightly
  5.  
  6.             class heading is different
  7.             vertical bar must appear between methods
  8.             syntax for primitives is different
  9.  
  10. */
  11.  
  12. /*      literals        */
  13. %token LITNUM LITFNUM LITCHAR LITSTR LITSYM
  14.  
  15. /*      basic objects   */
  16. %token CLASS ASSIGN BINARY PRIMITIVE NAMEDPRIM
  17.  
  18. /*      types of variables */
  19. %token PSEUDO UPPERCASEVAR LOWERCASEVAR COLONVAR KEYWORD
  20.  
  21. /*      one character symbols */
  22. %token LP RP LB RB PERIOD BAR MBAR SEMI UPARROW PS MINUS PE
  23. /*     (  )  [  ]  .      |   ^|   ;    ^       #  -     > */
  24.  
  25. %{
  26. # include "env.h"
  27. # include "drive.h"
  28. # include "parser.h"
  29. %}
  30.  
  31. %union {
  32.     struct litlist         *a;
  33.     struct blockstruct     *b;
  34.     char             *c;
  35.     struct exprstruct     *e;
  36.     int               i;
  37.     struct keylist         *k;
  38.     struct classstruct     *l;
  39.     struct methodstruct     *m;
  40.     struct objstruct     *o;
  41.     enum pseuvars          p;
  42.     struct primlist     *r;
  43.     struct statestruct     *s;
  44.     struct litstruct     *t;
  45.     struct primstruct     *u
  46.     }
  47.  
  48. %{
  49. extern struct blockstruct *mkblock();
  50. extern struct classstruct *mkclass();
  51. extern struct varstruct *mkvar(), *addvlist(), *invlist();
  52. extern struct methodstruct *mkmethod();
  53. extern struct exprstruct *mkexpr(), *mkkey();
  54. extern struct keylist *mkklist();
  55. extern struct statestruct *mkstate();
  56. extern struct objstruct *mkobj();
  57. extern struct primstruct *mkprim();
  58. extern struct primlist *addprim();
  59. extern struct litstruct *mklit();
  60. extern struct litlist *addlit();
  61. extern char   *bincat();
  62.  
  63. struct varstruct *instvars;
  64. struct varstruct *contextvars;
  65.  
  66. int bytetop = 0;
  67. uchar bytearray[1000];
  68.  
  69. YYSTYPE e;
  70. int errorcount = 0;
  71. %}
  72.  
  73. %type <a> litarray
  74. %type <b> block
  75. %type <c> CLASS KEYWORD LOWERCASEVAR UPPERCASEVAR COLONVAR LITSYM LITSTR
  76. %type <c> BINARY BAR MINUS UPARROW PE
  77. %type <c> classname binarysym binarychar
  78. %type <c> LITFNUM fliteral
  79. %type <e> pattern expression cexpression binary unary
  80. %type <e> kcontinuation bcontinuation ucontinuation
  81. %type <i> LITCHAR LITNUM PRIMITIVE NAMEDPRIM
  82. %type <i> tempvars cvarlist namelist barglist nliteral
  83. %type <k> keypattern keywordlist
  84. %type <l> super classheading
  85. %type <m> method methodlist
  86. %type <o> primary
  87. %type <p> PSEUDO
  88. %type <r> objlist
  89. %type <s> statelist statement sexpression opmessagelist
  90. %type <s> bstatelist bstatement bexpression
  91. %type <t> literal iliteral aliteral
  92. %type <u> primitive
  93.  
  94.  
  95. %start file
  96.  
  97. %%
  98. file    :       classdef
  99.         |       file classdef
  100.         ;
  101.  
  102. classdef:       classheading lb methodlist RB
  103.             {if (errorcount == 0) genclass($1, $3);}
  104.         ;
  105.  
  106. lb      :       LB
  107.         |       error   {if ((yytext[0] == ':') ||
  108.                              isalpha(yytext[0])) expect(":SuperClass");
  109.                          else expect("open brace [");}
  110.         ;
  111.  
  112. classheading:   class super instancevars {$$ = $2;}
  113.         ;
  114.  
  115. class   :       CLASS
  116.         |       error                   {expect("keyword Class");}
  117.         ;
  118.  
  119. super   :       classname                  {$$ = mkclass($1, (char *) 0);}
  120.         |       classname COLONVAR        {$$ = mkclass($1, $2);}
  121.         |       error                   {expect("Classname :Superclass");
  122.                                          $$ = mkclass("Error", (char *) 0);}
  123.         ;
  124.  
  125. classname:    UPPERCASEVAR
  126.     |    CLASS
  127.     ;
  128.  
  129. instancevars:   /* empty */
  130.         |       bar instvarlist bar
  131.         ;
  132.  
  133. instvarlist:    LOWERCASEVAR            {addinst($1);}
  134.         |       instvarlist LOWERCASEVAR    {addinst($2);}
  135.         |       error                       {expect("instance variable");}
  136.         ;
  137.  
  138. methodlist:     method            
  139.         |       methodlist MBAR method
  140.             {$3->nextmethod = $1; $$ = $3;}
  141.         ;
  142.  
  143. method  :       pattern tempvars statelist op
  144.             {deltemps($2); $$ = mkmethod($1, $2, $3);}
  145.         ;
  146.  
  147. pattern:        keypattern
  148. {$$ = mkkey((struct exprstruct *) 0, $1);}
  149.         |       binarysym argvariable
  150. {$$ = mkexpr((struct exprstruct *) 0, bincmd, $1, (struct exprstruct *) 0);}
  151.         |       LOWERCASEVAR
  152. {$$ = mkexpr((struct exprstruct *) 0, uncmd, $1, (struct exprstruct *) 0);}
  153.         |       error                   {expect("method pattern");
  154. $$ = mkexpr((struct exprstruct *) 0, uncmd, "", (struct exprstruct *) 0);}
  155.         ;
  156.  
  157. keypattern:     KEYWORD argvariable
  158. {$$ = mkklist((struct keylist *) 0, $1, (struct exprstruct *) 0);}
  159.         |       keypattern KEYWORD argvariable
  160. {$$ = mkklist($1, $2, (struct exprstruct *) 0);}
  161.         ;
  162.  
  163. argvariable:      LOWERCASEVAR            {addtemp($1, argvar);}
  164.         |         error                   {expect("argument variable");}
  165.         ;
  166.  
  167. tempvars:       /* empty */             {$$ = 0;}
  168.         |       bar namelist bar        {$$ = $2;}
  169.         ;
  170.  
  171. bar     :       BAR
  172.         |       MBAR
  173.         |       error                   {expect("| (vertical bar)");}
  174.         ;
  175.  
  176. namelist:       tvariable               {$$ = 1;}
  177.         |       namelist tvariable      {$$ = $1 + 1;}
  178.         ;
  179.  
  180. tvariable:      LOWERCASEVAR               {addtemp($1, tempvar);}
  181.         ;
  182.  
  183. statelist:    statement            {$$ = $1;}
  184.         |    statelist PERIOD statement    {$3->nextstate = $1; $$ = $3;}
  185.         ;
  186.  
  187. op    :    /* empty - optional period */
  188.     |    PERIOD
  189.     ;
  190.  
  191. statement:    UPARROW sexpression    {$$ = mkstate(upar, (char *) 0, $2);}
  192.     |    sexpression
  193.     ;
  194.  
  195. sexpression:    LOWERCASEVAR ASSIGN sexpression
  196.                 {$$ = mkstate(asgn, $1, $3);}
  197.     |    cexpression    
  198.     {$$ = mkstate(expr, (char *) 0, (struct statestruct *) $1);}
  199.     ;
  200.  
  201. cexpression:    expression
  202.     |    kcontinuation    {$$ = mkexpr($1, semiend, 0, 0);}
  203.     ;
  204.  
  205. kcontinuation:    bcontinuation
  206.     |    bcontinuation keywordlist {$$ = mkkey($1, $2);}
  207.     ;
  208.  
  209. bcontinuation:    ucontinuation
  210.     |    bcontinuation binarysym unary
  211.             {$$ = mkexpr($1, bincmd, $2, $3);}
  212.     ;
  213.  
  214. ucontinuation:    cexpression SEMI    {$$ = mkexpr($1, semistart, 0, 0);}
  215.     |    ucontinuation LOWERCASEVAR
  216.         {$$ = mkexpr($1, uncmd, $2, (struct exprstruct *) 0);}
  217.     ;
  218.  
  219. expression:     binary            {$$ = $1;}
  220.         |       binary keywordlist    {$$ = mkkey($1, $2);}
  221.         ;
  222.  
  223. keywordlist:    KEYWORD binary        
  224.             {$$ = mkklist((struct keylist *) 0, $1, $2);}
  225.         |       keywordlist KEYWORD binary
  226.             {$$ = mkklist($1, $2, $3);}
  227.         ;
  228.  
  229. binary  :       unary            {$$ = $1;}
  230.         |       binary binarysym unary    {$$ = mkexpr($1, bincmd, $2, $3);}
  231.         ;
  232.  
  233. binarysym:    binarychar        {$$ = $1;}
  234.     |    binarychar binarychar    {$$ = bincat($1, $2);}
  235.     ;
  236.  
  237. binarychar:      BINARY
  238.         |       BAR
  239.         |       MINUS
  240.         |       UPARROW
  241.     |    PE            
  242.         ;
  243.  
  244. unary   :       primary            
  245.         {$$ = mkexpr((struct exprstruct *) 0, reccmd, (char *) 0,
  246.                     (struct exprstruct *) $1);}
  247.         |       unary LOWERCASEVAR
  248.         {$$ = mkexpr($1, uncmd, $2, (struct exprstruct *) 0);}
  249.         ;
  250.  
  251. primary :    classname        {e.c = $1; $$ = mkobj(classobj, &e);}
  252.         |       LOWERCASEVAR        {e.c = $1; $$ = mkobj(varobj, &e);}
  253.         |       literal            {e.t = $1; $$ = mkobj(litobj, &e);}
  254.         |       PSEUDO            {e.p = $1; $$ = mkobj(pseuobj, &e);}
  255.     |    primitive        {e.u = $1; $$ = mkobj(primobj, &e);}
  256.         |       LP sexpression RP    {e.s = $2; $$ = mkobj(exprobj, &e);}
  257.     |    block             {e.b = $1; $$ = mkobj(blockobj, &e);}
  258.         ;
  259.  
  260. primitive:    PRIMITIVE LITNUM objlist PE
  261.                     {$$ = mkprim($2, $3);}
  262.     |    NAMEDPRIM objlist PE
  263.                     {$$ = mkprim($1, $2);}
  264.     ;
  265.  
  266. objlist :    /* empty */        {$$ = (struct primlist *) 0;}
  267.     |    objlist primary        {$$ = addprim($1, $2);}
  268.     ;
  269.  
  270. block    :    LB barglist opmessagelist RB
  271.                     {$$ = mkblock($2, $3);
  272.                     deltemps($2);}
  273.     ;
  274.  
  275. barglist :       /* empty */             {$$ = 0;}
  276.         |       cvarlist BAR            {$$ = $1;}
  277.         ;
  278.  
  279. cvarlist:       COLONVAR               {addtemp($1, argvar); $$ = 1;}
  280.         |       cvarlist COLONVAR      {addtemp($2, argvar); $$ = $1 + 1;}
  281.         ;
  282.  
  283. opmessagelist:    bstatelist bstatement     {$2->nextstate = $1; $$ = $2;}
  284.     |    bstatement         {$$ = $1;}
  285.     ;
  286.  
  287. bstatement:    UPARROW sexpression     {$$ = mkstate(blkupar, (char *) 0, $2);}
  288.     |    bexpression        {$$ = mkstate(upar, (char *) 0, $1);}
  289.     ;
  290.  
  291. bexpression:    /* empty */
  292. {e.p = nilvar;
  293. $$ = mkstate(expr, (char *) 0,
  294. (struct statestruct *) mkexpr((struct exprstruct *) 0, reccmd, (char *) 0,
  295.     (struct exprstruct *) mkobj(pseuobj, &e)));}
  296.     |    sexpression        {$$ = $1;}
  297.     ;
  298.  
  299. bstatelist:     sexpression PERIOD    {$$ = $1;}
  300.         |       bstatelist sexpression PERIOD
  301.             {$2->nextstate = $1; $$ = $2;}
  302.         ;
  303.  
  304. literal :       iliteral                {$$ = $1;}
  305.         |       alitstart litarray RP   {e.a = $2; $$ = mklit(arlit, &e);}
  306.         ;
  307.  
  308. alitstart:      PS LP
  309.         ;
  310.  
  311. iliteral:    fliteral        {e.c = $1; $$ = mklit(fnumlit, &e);}
  312.     |    nliteral        {e.i = $1; $$ = mklit(numlit, &e);}
  313.     |       LITCHAR                 {e.i = $1; $$ = mklit(charlit, &e);}
  314.         |       LITSTR                  {e.c = $1; $$ = mklit(strlit, &e);}
  315.         |       LITSYM                  {e.c = $1; $$ = mklit(symlit, &e);}
  316.         |       PS LB bytearray RB      {bytearray[bytetop] = '\0';
  317.                                          $$ = mklit(bytelit, &e);}
  318.         ;
  319.  
  320. fliteral:    LITFNUM            {$$ = $1;}
  321.     |     MINUS LITFNUM        {$$ = bincat("-", $2);}
  322.     ;
  323.  
  324. nliteral:    LITNUM            {$$ = $1;}
  325.     |    MINUS LITNUM        {$$ = - $2;}
  326.     ;
  327.  
  328. aliteral:       iliteral                {$$ = $1;}
  329.         |       LOWERCASEVAR            {e.c = $1; $$ = mklit(symlit, &e);}
  330.         |       UPPERCASEVAR            {e.c = $1; $$ = mklit(symlit, &e);}
  331.     |    KEYWORD            {e.c = $1; $$ = mklit(symlit, &e);}
  332.     |    COLONVAR        {e.c = $1; $$ = mklit(symlit, &e);}
  333.     |    CLASS            {e.c = $1; $$ = mklit(symlit, &e);}
  334.         |       binarysym               {e.c = $1; $$ = mklit(symlit, &e);}
  335.         |       ias litarray RP         {e.a = $2; $$ = mklit(arlit, &e);}
  336.         ;
  337.  
  338. ias     :       PS LP
  339.         |       LP
  340.         ;
  341.  
  342. litarray:       /* empty */             {$$ = (struct litlist *) 0;}
  343.         |       litarray aliteral       {$$ = addlit($1, $2);}
  344.         ;
  345.  
  346. bytearray:      LITNUM                  {bytetop = 0;
  347.                                          bytearray[bytetop++] = itouc($1);}
  348.         |       bytearray LITNUM        {bytearray[bytetop++] = itouc($2);}
  349.         ;
  350. %%
  351. # include <stdio.h>
  352.  
  353. char *filename;
  354. FILE *fp;
  355. FILE *ofd;
  356.  
  357. # include "lex.yy.c"
  358.  
  359. main(argc, argv)
  360. int argc;
  361. char **argv;
  362. {    
  363.     if (argc != 2) quiter("parser: wrong number of arguments");
  364.     filename = argv[1];
  365.     fp = fopen(filename, "r");
  366.     if (fp == NULL) {
  367.         yerr("cannot open input file %s", filename);
  368.         quiter("parser quits");
  369.         }
  370.     ofd = stdout;
  371.     return(yyparse());
  372. }
  373.  
  374. quiter(s) char *s; {fprintf(stderr,"%s\n", s); exit(1);}
  375.  
  376. yywarn(s, v) char *s, *v; {
  377.    fprintf(stderr, "%s: line %d: Warning ", filename, linenum);
  378.    fprintf(stderr, s, v);
  379.    fprintf(stderr,"\n");
  380. }
  381.  
  382. yyerror(s) char *s; {yerr(s, "");}
  383.  
  384. yerr(s, v)
  385. char *s, *v;
  386. {
  387.    fprintf(stderr, "%s: line %d: ", filename, linenum);
  388.    fprintf(stderr, s, v);
  389.    fprintf(stderr,"\n");
  390.    if (errorcount++ > 10) quiter("too many errors, goodby");
  391. }
  392.  
  393. expect(str) char *str;
  394. {  char buffer[100];
  395.  
  396.    sprintf(buffer,"Expected %%s found %s", yytext);
  397.    yerr(buffer, str);
  398. }
  399.  
  400. int yywrap() { return(1);}
  401.  
  402. char *alloc(size) int size;      /* allocate a block of storage */
  403. {  char *p, *malloc();
  404.  
  405.    p = malloc( (unsigned) size);
  406.    if (p == (char *) 0) yyerror("out of free space");
  407.    return(p);
  408. }
  409.  
  410. char *bincat(s1, s2)
  411. char *s1, *s2;
  412. {    char *p;
  413.  
  414.     p = alloc(strlen(s1) + strlen(s2) + 1);
  415.     strcpy(p, s1);
  416.     strcat(p, s2);
  417.     return(p);
  418. }
  419.